package ControlLayer;
import ModelLayer.Order;
import ModelLayer.OrderDetail;
import ModelLayer.Tax;
import ModelLayer.Product;
import ModelLayer.Customer;
import ModelLayer.Currency;
import ModelLayer.Employee;
import DBLayer.Constants;
import DBLayer.DBOrder;
import DBLayer.DBOrderDetail;
import DBLayer.DBTax;
import DBLayer.DBProduct;
import DBLayer.DBCustomer;
import DBLayer.DBCurrency;
import DBLayer.DBEmployee;
import GUILayer.UILogin;
import GUILayer.UIAddOrder;
import HWLayer.RS232Display;
import java.util.HashMap;

public class CtrMain {
    // <editor-fold defaultstate="collapsed" desc="Attributes & Constructors">
    private static CtrMain instance = null;
    RS232Display display        = new RS232Display("COM1");
    DBOrder dbOrder             = new DBOrder();
    DBOrderDetail dbOrderDetail = new DBOrderDetail();
    DBTax dbTax                 = new DBTax();
    DBProduct dbProduct         = new DBProduct();
    DBCustomer dbCustomer       = new DBCustomer();
    DBCurrency dbCurrency       = new DBCurrency();
    DBEmployee dbEmployee       = new DBEmployee();
    Employee employee           = new Employee();
    HashMap<String, Integer> productMap = new HashMap<String, Integer>();
    private int orderID;
    private int employeeID;
    float totalPrice = 0;

    public CtrMain() {
        //Clear display.
        display.sendClearDisplay();
    }
    // </editor-fold>

    // <editor-fold defaultstate="collapsed" desc="Methods">
    public static CtrMain getInstance() {
        if (instance == null) {
            instance = new CtrMain();
        }
        return instance;
    }

    //Returns the order list as a hashmap object.
    public HashMap getProductMap() {
        return productMap;
    }

    //Calculates and returns the total price including taxes.
    public float getTotalPrice() {
        return (Math.round(totalPrice * 125.0f) / 100.0f);
    }

    //Calculates and returns the tax value of the total price.
    public float getTotalTax() {
        return (Math.round(totalPrice * 25.0f) / 100.0f);
    }

    //Returns product oject from given ean13.
    public Product getProductByEan13(String ean13) {
        return dbProduct.getProductByEan13(ean13);
    }

    //Returns customer object from given ID.
    public Customer getCustomerByID(int id) {
        return dbCustomer.getCustomerByID(id);
    }

    //Returns currency object from given ID.
    public Currency getCurrencyByID(int id) {
        return dbCurrency.getCurrencyByID(id);
    }

    //Returns employee object from given email.
    public Employee getEmployeeByEmail(String email) {
        return dbEmployee.getEmployeeByEmail(email);
    }

    //Checks the given login information.
    public boolean checkLogin(String email, String hexString) {
        employee = getEmployeeByEmail(email);
        //Check if given email was found.
        if (employee.getIDEmployee() > 0) {
            String password = employee.getPasswd();
            //Compare passwords.
            if (password.equals(hexString)) {
                employeeID = employee.getIDEmployee();
                //Start Add Order GUI.
                new UIAddOrder().setVisible(true);
                return true;
            } else {
                //return false on invalid password.
                return false;
            }
        } else {
            //return false on invalid email.
            return false;
        }
    }

    //Adds a product to the order list by the given ean13.
    public boolean addProduct(String ean13) {
        Product product = getProductByEan13(ean13);
        //Check if given ean13 was found.
        if (product.getIDProduct() > 0) {
            //Check if given ean13 is already in the order list.
            if (productMap.containsKey(ean13)) {
                //Increase quantity.
                productMap.put(ean13, (productMap.get(ean13) + 1));
            } else {
                //Add product to order list.
                productMap.put(ean13, 1);
            }
            //Increase total price.
            totalPrice += product.getPrice();
            //Clear and write to display.
            display.sendClearDisplay();
            display.sendWriteLine(1, "Vare:");
            display.sendWriteLine(2, product.getName().substring(0, 20));
            display.sendWriteLine(3, "Pris:  " + addSpaces(product.getPrice()) + product.getPrice());
            display.sendWriteLine(4, "Total: " + addSpaces(getTotalPrice()) + getTotalPrice());
            //return true when product is added.
            return true;
        } else {
            //return false if given ean13 was not found.
            return false;
        }
    }

    //Adds the amount of spaces needed to align prices on the display.
    private String addSpaces(float price) {
        String returnString = new String();
        int spaces = 0;
        //Check price length.
        if (price < 10) {
            spaces = 9;
        } else if (price < 100) {
            spaces = 8;
        } else if (price < 1000) {
            spaces = 7;
        } else if (price < 10000) {
            spaces = 6;
        } else {
            spaces = 5;
        }
        //Add spaces to return string.
        for (int i = 0; i < spaces; i++) {
            returnString += " ";
        }
        return returnString;
    }

    //Writes the completed order to the database.
    public int createOrder() {
        //Create order object and add to database.
        Order order = new Order(0, 0, Constants.DEFAULT_LANGUAGE, Constants.CASH_CUSTOMER, 0, Constants.DEFAULT_CURRENCY, 0, 0, "", "Kontant", "cheque", false, false, "", "", 0, getTotalPrice(), getTotalPrice(), totalPrice, 0, 0, dbOrder.getNextInvoiceNumber(), 0, 0, 0, true, 0, 0);
        orderID = dbOrder.addOrder(order);
        //Create each orderdetail object and add to dabase.
        for (String key : productMap.keySet()) {
            Product product = getProductByEan13(key);
            Tax tax = dbTax.getTaxByID(product.getIDTax());
            OrderDetail orderDetail = new OrderDetail(0, orderID, product.getIDProduct(), 0, product.getName(), productMap.get(key), product.getQuantity(), 0, 0, 0, product.getPrice(), 0, key, product.getReference(), product.getSupplierReference(), product.getWeight(), tax.getName() , tax.getRate(), product.getEcotax(), "", 0, 0);
            dbOrderDetail.addOrderDetail(orderDetail);
        }
        //Return the new order ID.
        productMap.clear();
        totalPrice = 0;
        return orderID;
    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            public void run() {
                //Start Login UI.
                new UILogin().setVisible(true);
            }
        });
    }
    // </editor-fold>
}
